﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Lesson20 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #region 知识点一 回顾场景同步切换
        //SceneManager.LoadScene("Lesson20_test");
        #endregion

        #region 场景同步切换的缺点
        //在切换场景时
        // Unity会删除当前场景上所有对象
        //并且去加载下一个场景的相关信息
        //如果当前场景对象过多或者下一个场景对象过多
        //这个过行会非常的耗时会让玩家感受到卡顿

        //所以异步切换就是来解决该问题的
        #endregion

        #region 知识二 场景异步切换
        //场景异步加载和资源异步加载几乎一致有两种方式
        //1.通过事件回调函数异步加载
        //AsyncOperation ao = SceneManager.LoadSceneAsync("Lesson20_test");
        //当场景异步加载结束后就会自动调用该事件函数我们如果希望在加载结束后做一些事情那么久可以在该函数虫
        //写处理逻辑
        //ao.completed += (a) =>
        //{
        //    Debug.LogFormat("加载完成...");
        //};

        //2.通过协程异步加载
        //需要注意的是加载场景会把当前场景上没有特别处理的对象 都删除了
        //所以协程中的部分逻辑可能是执行不了的
        //解决思路
        //让处理场景加载的脚本依附的对象过场景时不被移除

        //该脚本依附的对象 过场景时 不会被移除
        DontDestroyOnLoad(this.gameObject);

        StartCoroutine(LoadScene("Lesson20_test"));
        #endregion

        #region 总结
        //场景异步加载和资源异步加载一样
        //有两种方式
        //1。通过事件回调函数
        //2.协程异步加载

        //他们的优缺点表现和资源异步加载也是一样的
        //1.事件回调函数
        //优点:写法简单，逻辑清晰
        //缺点:只能加载完场景做一些事情不能再加载过程中处理逻辑
        //2.协程异步加载
        //优先:可以在加载过程中处理逻辑，比如进度条更新等
        //缺点:写法较为麻烦，要通过协程
        #endregion
    }

    IEnumerator LoadScene(string name)
    {
        //第一步
        //异步加载场景
        AsyncOperation ao = SceneManager.LoadSceneAsync(name);
        //Unity内部的 协程协调器 发现是异步加载类型的返回对象 那么就会等待
        //等待异步加载结束后 才会继续执行 迭代器函数中后面的步骤
        //协程的好处 是异步加载场景时 可以在加载的同时 做一些别的逻辑
        Debug.LogFormat("异步加载过程中 打印的信息");
        //yield return ao;
        //第二步(由于异步加载完成切换场景会将当前场景上的脚本移除，所以下面的代码不会被执行)
        //在Start函数中使用了设置了不被移除的脚本后，这行代码会被正确执行
        Debug.LogFormat("异步加载结束后 打印的信息...");

        //比如 我们可以在异步加载过程中 去更新进度条
        //第一种 得用场景异步加载的进度 去更新 但是 不是特别准确 一般也不会直接用
        while (!ao.isDone)
        {
            Debug.LogFormat("progress:{0}", ao.progress);
            yield return null;
        }

        //离开循环后 就会认为场景加载结束
        //可以把进度条顶满 然后隐藏进度条

        //第二种 根据游戏规则 自己定义 进度条变化的条件
        yield return ao;
        //场景加载结束 更新20%进度
        //接着去加载场景中的其它信息
        //比如
        //动态加载怪物
        //这时 进度条再更新20%
        //动态加载场景模型
        //加载结束，隐藏进度条
    }
}
